package com.ease.job.quartz.job;

import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/**
 * http://blog.csdn.net/lifetragedy/article/details/6212831 http://forhope.iteye.com/blog/1398990
 * 
 * @author nathanleewei
 */
public class MethodInvokingStatefulCronJob extends AbstractStatefulCronJob {

	/**
	 *
	 */
	private static final long serialVersionUID = -1696630722153840752L;

	private static final transient Log log = LogFactory.getLog(MethodInvokingStatefulCronJob.class);

	private String targetBeanName;

	private Object targetObject;

	private String targetMethod;

	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

		// System.out.println(JsonUtil.marshal(context));

		targetObject = this.getBean(targetBeanName);

		Method method = null;
		try {
			method = targetObject.getClass().getMethod(targetMethod, new Class[] { JobExecutionContext.class });
		} catch (Exception e) {

		}

		if (null != method) {
			try {
				method.invoke(targetObject, new Object[] { context });
			} catch (Exception e) {
				log.error("targetObject=" + targetObject + ",targetMethod" + targetMethod, e);
			}
		} else {

			try {
				method = targetObject.getClass().getMethod(targetMethod, new Class[0]);
			} catch (Exception e) {
				log.error("targetObject=" + targetObject + ",targetMethod" + targetMethod, e);
			}

			if (null == method) {
				throw new RuntimeException("targetMethod not found, targetObject=" + targetObject + ",targetMethod" + targetMethod);
			}

			try {
				method.invoke(targetObject, new Object[0]);
			} catch (Exception e) {
				log.error("targetObject=" + targetObject + ",targetMethod" + targetMethod, e);
			}

		}
	}

	/**
	 * @return the targetMethod
	 */
	public String getTargetMethod() {
		return targetMethod;
	}

	/**
	 * @param targetMethod
	 *            the targetMethod to set
	 */
	public void setTargetMethod(String targetMethod) {
		this.targetMethod = targetMethod;
	}

	/**
	 * @return the targetBeanName
	 */
	public String getTargetBeanName() {
		return targetBeanName;
	}

	/**
	 * @param targetBeanName
	 *            the targetBeanName to set
	 */
	public void setTargetBeanName(String targetBeanName) {
		this.targetBeanName = targetBeanName;
	}

	/**
	 * @return the targetObject
	 */
	public Object getTargetObject() {
		return targetObject;
	}

	/**
	 * @param targetObject
	 *            the targetObject to set
	 */
	public void setTargetObject(Object targetObject) {
		this.targetObject = targetObject;
	}
}
